package com.order.manager.controller.Online;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.order.manager.Model.OnlineInfo;
import com.order.manager.Model.OrderInfo;
import com.order.manager.Model.SenderInfo;
import com.order.manager.Model.ShopInfo;
import com.order.manager.Model.other.RestBean;
import com.order.manager.service.impl.*;
import com.order.manager.util.JwtUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;

/**
 * 在线聊天控制器
 * 处理用户、商家、配送员之间的聊天消息发送和历史记录查询
 */
@RestController
@RequestMapping("/api/online")
public class OnlineController {
    // 注入在线聊天信息服务，处理聊天消息的数据库操作
    @Resource
    OnlineInfoServiceImpl onlineInfoService;
    // 注入JWT工具类，用于解析用户身份信息
    @Resource
    JwtUtil jwtUtil;
    // 注入店铺信息服务，用于获取店铺相关信息
    @Resource
    ShopInfoServiceImpl shopInfoService;
    // 注入配送员信息服务，用于获取配送员相关信息
    @Resource
    SenderInfoServiceImpl senderInfoService;
    // 注入订单信息服务，用于获取订单相关信息
    @Resource
    OrderInfoServiceImpl orderInfoService;

    /**
     * 用户向商家发送聊天消息
     * @param request HTTP请求对象，用于获取用户JWT
     * @param orderId 订单ID，通过路径变量传入
     * @param content 聊天内容，通过请求参数传入
     * @return 操作结果：成功返回消息对象，失败返回错误信息
     */
    @RequestMapping("/chat/shop/{orderId}")
    public RestBean getChatWithShop(HttpServletRequest request, @PathVariable String orderId, String content) {
        // 创建聊天消息实体
        OnlineInfo onlineInfo = new OnlineInfo();
        // 根据订单ID查询订单信息
        OrderInfo orderInfo = orderInfoService.getById(orderId);
        // 校验订单是否存在
        if (orderInfo == null) return RestBean.failure(400, "没有订单信息");
        // 从JWT中获取用户ID
        String uuid = jwtUtil.getJwtUsername(request);
        // 根据订单中的店铺ID查询店铺信息
        ShopInfo shopInfo = shopInfoService.getById(orderInfo.getShopId());
        // 校验店铺是否存在
        if (shopInfo == null) return RestBean.failure(400, "不存在该商铺信息");
        // 获取店铺主人ID
        String shopMasterId = shopInfo.getShopMasterId();
        // 设置消息发送者ID（用户ID）
        onlineInfo.setSendId(uuid);
        // 设置消息接收者ID（店铺主人ID）
        onlineInfo.setReceiveId(shopMasterId);
        // 设置消息内容
        onlineInfo.setContent(content);
        // 设置消息发送时间
        onlineInfo.setSendTime(new Date());
        // 保存消息到数据库
        return onlineInfoService.save(onlineInfo) ? RestBean.success(onlineInfo) : RestBean.failure(500, "聊天失败");
    }

    /**
     * 商家向用户发送聊天消息
     * @param request HTTP请求对象，用于获取用户JWT
     * @param userId 用户ID，通过路径变量传入
     * @param content 聊天内容，通过请求参数传入
     * @return 操作结果：成功返回消息对象，失败返回错误信息
     */
    @RequestMapping("/chat/user/{userId}")
    public RestBean getChatWithUser(HttpServletRequest request, @PathVariable String userId, String content) {
        // 创建聊天消息实体
        OnlineInfo onlineInfo = new OnlineInfo();
        // 从JWT中获取用户ID（当前操作用户为商家）
        String uuid = jwtUtil.getJwtUsername(request);
        // 校验商家是否有店铺
        if (shopInfoService.count(new QueryWrapper<ShopInfo>()
                .eq("shop_master_id", uuid)
        ) == 0) {
            return RestBean.failure(400, "没有店铺信息");
        }
        // 获取商家的店铺信息
        ShopInfo shopMasterId = shopInfoService.getOne(new QueryWrapper<ShopInfo>()
                .eq("shop_master_id", uuid)
        );
        // 设置消息发送者ID（商家ID）
        onlineInfo.setSendId(shopMasterId.getShopMasterId());
        // 设置消息接收者ID（用户ID）
        onlineInfo.setReceiveId(userId);
        // 设置消息内容
        onlineInfo.setContent(content);
        // 设置消息发送时间
        onlineInfo.setSendTime(new Date());
        // 保存消息到数据库
        return onlineInfoService.save(onlineInfo) ? RestBean.success(onlineInfo) : RestBean.failure(500, "聊天失败");
    }

    /**
     * 用户向配送员发送聊天消息
     * @param request HTTP请求对象，用于获取用户JWT
     * @param senderId 配送员ID，通过路径变量传入
     * @param content 聊天内容，通过请求参数传入
     * @return 操作结果：成功返回消息对象，失败返回错误信息
     */
    @RequestMapping("/chat/sender/{senderId}")
    public RestBean getChatWithSenderId(HttpServletRequest request, @PathVariable String senderId, String content) {
        // 创建聊天消息实体
        OnlineInfo onlineInfo = new OnlineInfo();
        // 从JWT中获取用户ID
        String uuid = jwtUtil.getJwtUsername(request);
        // 根据配送员ID查询配送员信息
        SenderInfo senderInfo = senderInfoService.getById(senderId);
        // 校验配送员是否存在
        if (senderInfo == null) return RestBean.failure(400, "不存在该配送员信息");
        // 获取配送员的用户ID
        String senderInfoUserId = senderInfo.getUserId();
        // 设置消息发送者ID（用户ID）
        onlineInfo.setSendId(uuid);
        // 设置消息接收者ID（配送员用户ID）
        onlineInfo.setReceiveId(senderInfoUserId);
        // 设置消息内容
        onlineInfo.setContent(content);
        // 设置消息发送时间
        onlineInfo.setSendTime(new Date());
        // 保存消息到数据库
        return onlineInfoService.save(onlineInfo) ? RestBean.success(onlineInfo) : RestBean.failure(500, "聊天失败");
    }

    /**
     * 获取用户与商家的所有聊天记录
     * @param orderId 订单ID，通过路径变量传入
     * @param request HTTP请求对象，用于获取用户JWT
     * @return 操作结果：成功返回聊天记录列表，失败返回错误信息
     */
    @RequestMapping("/all/chat/shop/{orderId}")
    public RestBean GetChatAllShop(@PathVariable String orderId, HttpServletRequest request) {
        // 从JWT中获取用户ID
        String uuid = jwtUtil.getJwtUsername(request);
        // 根据订单ID查询订单信息
        OrderInfo orderInfo = orderInfoService.getById(orderId);
        // 校验订单是否存在
        if (orderInfo == null) return RestBean.failure(400, "没有该订单信息");
        // 根据订单中的店铺ID查询店铺信息
        ShopInfo shopInfo = shopInfoService.getById(orderInfo.getShopId());
        // 校验店铺是否存在
        if (shopInfo == null) return RestBean.failure(400, "没有该店铺信息");
        // 查询用户发给商家的消息
        List<OnlineInfo> onlineInfos1 = onlineInfoService.list(new QueryWrapper<OnlineInfo>().eq("send_id", uuid).eq("receive_id", shopInfo.getShopMasterId()));
        // 查询商家发给用户的消息
        List<OnlineInfo> onlineInfos2 = onlineInfoService.list(new QueryWrapper<OnlineInfo>().eq("send_id", shopInfo.getShopMasterId()).eq("receive_id", uuid));
        // 合并消息列表
        List<OnlineInfo> onlineInfos = new ArrayList<>();
        onlineInfos.addAll(onlineInfos1);
        onlineInfos.addAll(onlineInfos2);
        // 创建时间比较器，用于按时间排序消息
        Comparator<OnlineInfo> comparator = new Comparator<OnlineInfo>() {
            public int compare(OnlineInfo o1, OnlineInfo o2) {
                return o1.getSendTime().compareTo(o2.getSendTime());
            }
        };
        // 按时间排序消息列表
        Collections.sort(onlineInfos, comparator);
        // 格式化消息内容，添加发送者标识和时间
        onlineInfos.forEach(el -> {
            if (el.getSendId().equals(uuid)) {
                el.setContent("我：" + el.getContent() + "            " + JSON.toJSONString(el.getSendTime()));
            } else {
                el.setContent("商家：" + el.getContent() + "            " + JSON.toJSONString(el.getSendTime()));
            }
        });
        // 返回排序并格式化后的消息列表
        return RestBean.success(onlineInfos);
    }

    /**
     * 获取商家与用户的所有聊天记录
     * @param userId 用户ID，通过路径变量传入
     * @param request HTTP请求对象，用于获取用户JWT
     * @return 操作结果：成功返回聊天记录列表，失败返回错误信息
     */
    @RequestMapping("/all/chat/user/{userId}")
    public RestBean GetChatAllUser(@PathVariable String userId, HttpServletRequest request) {
        // 从JWT中获取用户ID（当前操作用户为商家）
        String uuid = jwtUtil.getJwtUsername(request);
        // 校验商家是否有店铺
        if (shopInfoService.count(new QueryWrapper<ShopInfo>()
                .eq("shop_master_id", uuid)
        ) == 0) {
            return RestBean.failure(400, "不存在店铺信息");
        }
        // 获取商家的店铺信息
        ShopInfo shopMasterId = shopInfoService.getOne(new QueryWrapper<ShopInfo>()
                .eq("shop_master_id", uuid)
        );
        // 查询用户发给商家的消息
        List<OnlineInfo> onlineInfos1 = onlineInfoService.list(new QueryWrapper<OnlineInfo>().eq("send_id", userId).eq("receive_id", shopMasterId.getShopMasterId()));
        // 查询商家发给用户的消息
        List<OnlineInfo> onlineInfos2 = onlineInfoService.list(new QueryWrapper<OnlineInfo>().eq("send_id", shopMasterId.getShopMasterId()).eq("receive_id", userId));
        // 合并消息列表
        List<OnlineInfo> onlineInfos = new ArrayList<>();
        onlineInfos.addAll(onlineInfos1);
        onlineInfos.addAll(onlineInfos2);
        // 创建时间比较器，用于按时间排序消息
        Comparator<OnlineInfo> comparator = new Comparator<OnlineInfo>() {
            public int compare(OnlineInfo o1, OnlineInfo o2) {
                return o1.getSendTime().compareTo(o2.getSendTime());
            }
        };
        // 按时间排序消息列表
        Collections.sort(onlineInfos, comparator);
        // 格式化消息内容，添加发送者标识和时间
        onlineInfos.forEach(el -> {
            if (el.getSendId().equals(userId)) {
                el.setContent("客户：" + el.getContent() + "            " + JSON.toJSONString(el.getSendTime()));
            } else {
                el.setContent("我：" + el.getContent() + "            " + JSON.toJSONString(el.getSendTime()));
            }
        });
        // 返回排序并格式化后的消息列表
        return RestBean.success(onlineInfos);
    }

    /**
     * 获取用户与配送员的所有聊天记录
     * @param senderId 配送员ID，通过路径变量传入
     * @param request HTTP请求对象，用于获取用户JWT
     * @return 操作结果：成功返回聊天记录列表，失败返回错误信息
     */
    @RequestMapping("/all/chat/sender/{senderId}")
    public RestBean GetChatAllSender(@PathVariable String senderId, HttpServletRequest request) {
        // 从JWT中获取用户ID
        String uuid = jwtUtil.getJwtUsername(request);
        // 根据配送员ID查询配送员信息
        SenderInfo senderInfo = senderInfoService.getById(senderId);
        // 校验配送员是否存在
        if (senderInfo == null) return RestBean.failure(400, "没有该配送员信息");
        // 查询用户发给配送员的消息
        List<OnlineInfo> onlineInfos1 = onlineInfoService.list(new QueryWrapper<OnlineInfo>().eq("send_id", uuid).eq("receive_id", senderInfo.getUserId()));
        // 查询配送员发给用户的消息
        List<OnlineInfo> onlineInfos2 = onlineInfoService.list(new QueryWrapper<OnlineInfo>().eq("send_id", senderInfo.getUserId()).eq("receive_id", uuid));
        // 合并消息列表
        List<OnlineInfo> onlineInfos = new ArrayList<>();
        onlineInfos.addAll(onlineInfos1);
        onlineInfos.addAll(onlineInfos2);
        // 创建时间比较器，用于按时间排序消息
        Comparator<OnlineInfo> comparator = new Comparator<OnlineInfo>() {
            public int compare(OnlineInfo o1, OnlineInfo o2) {
                return o1.getSendTime().compareTo(o2.getSendTime());
            }
        };
        // 按时间排序消息列表
        Collections.sort(onlineInfos, comparator);
        // 返回排序后的消息列表
        return RestBean.success(onlineInfos);
    }
}